package http

import (
	"github.com/edgexfoundry/edgex-go/internal/app/core/metadata/application"
	"github.com/edgexfoundry/edgex-go/internal/app/dtos/requests"
	"github.com/edgexfoundry/edgex-go/internal/app/dtos/responses"
	metadataContainer "github.com/edgexfoundry/edgex-go/internal/core/metadata/container"
	"github.com/edgexfoundry/edgex-go/internal/io"
	"github.com/edgexfoundry/edgex-go/internal/pkg"
	"github.com/edgexfoundry/edgex-go/internal/pkg/utils"
	"github.com/edgexfoundry/go-mod-bootstrap/v2/bootstrap/container"
	"github.com/edgexfoundry/go-mod-bootstrap/v2/di"
	commonDTO "github.com/edgexfoundry/go-mod-core-contracts/v2/dtos/common"
	"github.com/gorilla/mux"
	"math"
	"net/http"
)

type ProductFunctionController struct {
	reader io.DtoReader
	dic    *di.Container
}

func NewProductFunctionController(dic *di.Container) *ProductFunctionController {
	return &ProductFunctionController{
		reader: io.NewJsonDtoReader(),
		dic:    dic,
	}
}

//AddProductFunction 添加产品功能
func (pmc *ProductFunctionController) AddProductFunction(w http.ResponseWriter, r *http.Request) {
	if r.Body != nil {
		defer func() { _ = r.Body.Close() }()
	}

	lc := container.LoggingClientFrom(pmc.dic.Get)
	ctx := r.Context()
	//correlationId := correlation.FromContext(ctx)

	var reqDTO requests.AddProductFunctionRequest
	err := pmc.reader.Read(r.Body, &reqDTO)
	if err != nil {
		utils.WriteErrorResponse(w, ctx, lc, err, "")
		return
	}
	productFunction := requests.AddProductFunctionReqToProductFunctionModel(reqDTO)
	newId, err := application.AddProductFunction(productFunction, ctx, pmc.dic)

	var response interface{}
	if err != nil {
		response = commonDTO.NewBaseResponse(
			reqDTO.RequestId,
			err.Message(),
			err.Code())
	} else {
		response = commonDTO.NewBaseWithIdResponse(
			reqDTO.RequestId,
			"",
			http.StatusCreated,
			newId)
	}
	utils.WriteHttpHeader(w, ctx, http.StatusOK)
	pkg.EncodeAndWriteResponse(response, w, lc)
}

// AllFunctionsByProductId 查询产品的功能
func (pmc *ProductFunctionController) AllFunctionsByProductId(w http.ResponseWriter, r *http.Request) {
	lc := container.LoggingClientFrom(pmc.dic.Get)
	ctx := r.Context()
	config := metadataContainer.ConfigurationFrom(pmc.dic.Get)

	vars := mux.Vars(r)
	productId := vars["productid"]

	offset, limit, _, err := utils.ParseGetAllObjectsRequestQueryString(r, 0, math.MaxInt32, -1, config.Service.MaxResultCount)
	if err != nil {
		utils.WriteErrorResponse(w, ctx, lc, err, "")
		return
	}
	productFunctions, totalCount, err := application.AllFunctionsByProductId(offset, limit, productId, pmc.dic)
	if err != nil {
		utils.WriteErrorResponse(w, ctx, lc, err, "")
		return
	}
	response := responses.NewMultiProductFunctionsResponse("", "", http.StatusOK, totalCount, productFunctions)
	utils.WriteHttpHeader(w, ctx, http.StatusOK)
	pkg.EncodeAndWriteResponse(response, w, lc)
}

// ProductFunctionDelete 删除产品功能
func (pmc *ProductFunctionController) ProductFunctionDelete(w http.ResponseWriter, r *http.Request) {
	if r.Body != nil {
		defer func() { _ = r.Body.Close() }()
	}
	lc := container.LoggingClientFrom(pmc.dic.Get)
	ctx := r.Context()

	var reqDTOs []string
	err := pmc.reader.Read(r.Body, &reqDTOs)
	if err != nil {
		utils.WriteErrorResponse(w, ctx, lc, err, "")
		return
	}

	err = application.ProductFunctionDelete(reqDTOs, pmc.dic)
	if err != nil {
		utils.WriteErrorResponse(w, ctx, lc, err, "")
		return
	}
	response := commonDTO.NewBaseResponse("", "", http.StatusOK)
	utils.WriteHttpHeader(w, ctx, http.StatusOK)
	pkg.EncodeAndWriteResponse(response, w, lc)
}

// UpdateProductFunction 更新产品功能
func (pmc *ProductFunctionController) UpdateProductFunction(w http.ResponseWriter, r *http.Request) {
	if r.Body != nil {
		defer func() { _ = r.Body.Close() }()
	}
	lc := container.LoggingClientFrom(pmc.dic.Get)
	ctx := r.Context()

	var reqDTO requests.UpdateProductFunctionRequest
	err := pmc.reader.Read(r.Body, &reqDTO)
	if err != nil {
		utils.WriteErrorResponse(w, ctx, lc, err, "")
		return
	}
	productFunction := requests.UpdateFunctionReqToFunctionModel(reqDTO)
	edgeXerr := application.UpdateProductFunction(productFunction, pmc.dic)

	if edgeXerr != nil {
		utils.WriteErrorResponse(w, ctx, lc, edgeXerr, "")
		return
	}
	response := commonDTO.NewBaseResponse("", "", http.StatusOK)
	utils.WriteHttpHeader(w, ctx, http.StatusOK)
	pkg.EncodeAndWriteResponse(response, w, lc)
}
